package com.google.code.jtasks.model;

import com.google.code.jtasks.manager.cache.TaskEnumsRegistry;

/**
 * Models the resolution of tasks: the reason that they were completed, or not. The {@link Resolution}
 * {@link #getLabel()} values are generally specific to the task system, but {@link #isClosed()} and
 * {@link #isValid()} can be used to work with resolutions in a standard way.
 */
public final class Resolution
{
	private final boolean closed;
	private final String label;

	/**
	 * <p>
	 * Constructs a new {@link Resolution} instance.
	 * </p>
	 * <p>
	 * Generally, users should avoid creating new {@link Resolution} instances themselves and should instead
	 * retrieve them from the {@link TaskEnumsRegistry} for the task system in use.
	 * </p>
	 * 
	 * @param closed
	 *            <code>true</code> if this {@link Resolution} indicates that the task was closed/resolved,
	 *            <code>false</code> if it indicates that the task is still open
	 * @param label
	 *            the label used by the task system to identify the {@link Resolution}
	 */
	public Resolution(boolean closed, String label)
	{
		if (label == null)
			throw new IllegalArgumentException("null label not allowed");

		this.closed = closed;
		this.label = label;
	}

	/**
	 * Returns <code>true</code> if this {@link Resolution} indicates that the task was closed/resolved,
	 * <code>false</code> if it indicates that the task is still open.
	 * 
	 * @return <code>true</code> if this {@link Resolution} indicates that the task was closed/resolved,
	 *         <code>false</code> if it indicates that the task is still open
	 */
	public boolean isClosed()
	{
		return closed;
	}

	/**
	 * Returns the label used by the task system to identify the {@link Resolution}.
	 * 
	 * @return the label used by the task system to identify the {@link Resolution}
	 */
	public String getLabel()
	{
		return label;
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj)
	{
		if (obj == null || !(obj instanceof Resolution))
			return super.equals(obj);
		Resolution other = (Resolution) obj;

		if (closed != other.closed)
			return false;
		if (!label.equals(other.label))
			return false;

		return true;
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode()
	{
		int hash = new Boolean(closed).hashCode();
		hash ^= label.hashCode();

		return hash;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		StringBuilder debugText = new StringBuilder();
		debugText.append(this.getClass().getSimpleName());
		debugText.append("[");
		debugText.append("closed=");
		debugText.append(closed);
		debugText.append(",label=");
		debugText.append(label);
		debugText.append("]");
		return debugText.toString();
	}
}
